package comunicacao;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

import empacotador.PacoteDeDados;
import empacotador.UnsignedByte;

public class Comunicacao implements Runnable, SerialPortEventListener {
	
	private SerialPort porta;
	private InputStream entrada;
	private OutputStream saida;
	private Thread threadLeitura;
	
	private int tamanhoPacote=0;
	
	private ArrayList<Integer> bufferPacote = new ArrayList<Integer>();
	
	public Comunicacao() throws NoSuchPortException, PortInUseException, IOException
	{
		
		CommPortIdentifier cp = CommPortIdentifier.getPortIdentifier("/dev/ttyS0");		
		porta = (SerialPort)cp.open("SComm",1000);
		
		try {
			configurarPorta();
		} catch (UnsupportedCommOperationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

		saida = porta.getOutputStream();
		
		
	}
	
	private void listarPortas()
	{
		/*
		 * lista de portas
		 */
		Enumeration listaDePortas;
		listaDePortas = CommPortIdentifier.getPortIdentifiers();

		int i = 0;
		String[] portas = new String[10];
		while (listaDePortas.hasMoreElements()) {
			CommPortIdentifier ips = (CommPortIdentifier)listaDePortas.nextElement();
			portas[i] = ips.getName();
			//System.out.println(ips.getName());
			i++;
		}		
	}
	

	private void configurarPorta() throws UnsupportedCommOperationException
	{

		System.out.println(""); //Evita excecao no linux
		porta.setSerialPortParams(9600, porta.DATABITS_8, porta.STOPBITS_1, porta.PARITY_NONE);
	}
	
	public void lerDados() throws IOException
	{
		entrada = porta.getInputStream();
		
		try {
			porta.addEventListener(this);
		} catch (TooManyListenersException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		threadLeitura = new Thread(this);
		threadLeitura.start();

		porta.notifyOnDataAvailable(true);
		
	}
	
	public void serialEvent(SerialPortEvent ev){
		switch (ev.getEventType()) {

			case SerialPortEvent.DATA_AVAILABLE:
				byte[] buffer = new byte[255];
				int[] dados;
				int lidos = 0;
				try {
					
					while ( entrada.available() > 0 ) {
						lidos =  entrada.read(buffer);	
					}

					char[] dados1 = UnsignedByte.toUnsigned(buffer,0,lidos);

          for (char c :dados1)
            System.out.println(c);

					//if (tamanhoPacote == 0 && bufferPacote.size() > 2)
					if (tamanhoPacote == 0 && bufferPacote.size() > 1)
					{
						//tamanhoPacote =  bufferPacote.get(2)*256+bufferPacote.get(3);
						tamanhoPacote =  bufferPacote.get(1);
						System.out.println("TAMANHO DO PACOTE = "+tamanhoPacote);
					}
/*
					
					if (tamanhoPacote > 0 && (bufferPacote.size()+dados.length) > tamanhoPacote)
					{
						System.out.println("RECEBIDO PACOTE ("+tamanhoPacote+")");
						
					 
            //FIXME - CRIAR PACOTE

						ArrayList<Integer> restoBufferPacote = new ArrayList<Integer>();
						System.out.println(tamanhoPacote);
						System.out.println(bufferPacote.size());
						
						for(int i=(tamanhoPacote-bufferPacote.size()); i<dados.length; i++)
							restoBufferPacote.add(dados[i]);
						
						tamanhoPacote = 0;
						bufferPacote = restoBufferPacote;
						

						
					} else {
            System.out.println("Buffering "+dados.length+" bytes");
						for (int i : dados) {
							bufferPacote.add(i);	
						}
						
					}

*/

					
				} catch (Exception e) {
					e.printStackTrace();
					System.exit(0);
				}
				
			break;
		}
	}
	
	public void envia(byte[] data) throws IOException
	{
		saida.write(data);
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		saida.flush();
		
	}


	public void run() {
		try {
			Thread.sleep(5000); //NAO ENTENDO PARA QUE ESSE SLEEP 
		} catch (Exception e) {
			System.out.println("Erro. Status = " + e );
			e.printStackTrace();
		}
		// TODO Auto-generated method stub
		
	}
	
	public void fechar(){
		try {
			porta.close();
			System.out.println("CONEXAO FECHADA>>FIM..");
		} catch (Exception e) {
			System.out.println("ERRO AO FECHAR. STATUS: " + e );
			System.exit(0);
		}
	}
}
